<template>
  <view class="mxp-collapse-item" :style="[cusStyle]" :class="[cusClass, disabled ? 'disabled' : '']">
    <view class="title-vessel" :style="[newTitleViewStyle]" @click="onClick">
      <view class="title-view" :hoverClass="hover && !disabled ? 'hover' : 'none'" :hoverStartTime="0" :hoverStayTime="0">
        <mxp-icon v-if="iconPosition === 'left'" name="xiajiantou" :size="iconSize" :color="iconColor" :cusStyle="newIconStyle"></mxp-icon>
        <view style="flex: 1">
          <slot name="title">
            <text :style="[newTitleStyle, { fontSize: titleSize, color: titleColor }]">{{ title }}</text>
          </slot>
        </view>
        <mxp-icon v-if="iconPosition === 'right'" key="mxp-icon-2" name="xiajiantou" :size="iconSize" :color="iconColor" :cusStyle="newIconStyle"></mxp-icon>
        <slot name="rightLabel"></slot>
      </view>
      <mxp-line
        v-if="(isLast && (showLastborder || (!showLastborder && isUnFold))) || (!isLast && newBorderColor)"
        :color="newBorderColor"
        :cusStyle="lineStyle"
      ></mxp-line>
    </view>
    <view class="fold-view" :style="{ height: contentHeight, transitionDuration: duration + 'ms' }">
      <view :id="id" class="content-view" :style="[contentViewStyle]">
        <view style="display: flex">
          <slot>
            <text class="content" :style="[newContentTextStyle]">{{ content }}</text>
          </slot>
        </view>
        <mxp-line v-if="(isLast && showLastborder && isUnFold) || (!isLast && isUnFold)" :cusStyle="lineStyle" :color="borderColor"></mxp-line>
      </view>
    </view>
  </view>
</template>

<script lang="ts" setup>
  import { publicStyeProps } from '../mxp-tool/utils/public-props';
  import { type CSSProperties, type PropType, computed, getCurrentInstance, inject, onMounted, ref, watch } from 'vue';
  import { getDomSize } from '../mxp-tool/utils/dom';
  import MxpIcon from '../mxp-icon/mxp-icon.vue';
  import MxpLine from '@/mxp-ui/mxp-line/mxp-line.vue';
  import type { $AllColorStr, $SizeUnitStr } from '@/mxp-ui/mxp-tool/types/interface';
  import { getOnlyID } from '../mxp-tool/utils/common';
  import { type CollapseID, type MxpCollapseProps, collapseInjectKey, mxpCollapseStore } from '../mxp-tool/store/mxp-store-collapse';

  defineOptions({
    name: 'mxp-collapse-item',
  });

  const props = defineProps({
    /** 标题上下框颜色(如不需要边框可设为fasle) */
    borderColor: { type: [Boolean, String] as PropType<$AllColorStr | boolean>, default: undefined },
    /** 是否有点击效果 */
    hover: { type: Boolean, default: true },
    /** 标题 */
    title: { type: String, default: '' },
    /** 标题的字体大小 */
    titleSize: { type: String as PropType<$SizeUnitStr>, default: '15px' },
    /** 标题的颜色 */
    titleColor: { type: String as PropType<$AllColorStr>, default: '#333333' },
    /** 标题的样式 */
    titleStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
    /** 标题容器的样式 */
    titleViewStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
    /** 标题栏最小高度 */
    titleViewMinHeight: { type: String as PropType<$SizeUnitStr>, default: '48px' },
    /** 标识，用来展开和关闭的标识 */
    name: { type: [Number, String], default: '' },
    /** icon的样式 */
    iconStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
    /** icon的大小 */
    iconSize: { type: String as PropType<$SizeUnitStr>, default: '15px' },
    /** icon的颜色 */
    iconColor: { type: String as PropType<$AllColorStr>, default: '#999999' },
    /** 内容文本 */
    content: { type: [Number, String], default: '' },
    /** 线条样式 */
    lineStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
    /** 内容文本的字体大小 */
    contentSize: { type: String as PropType<$SizeUnitStr>, default: '14px' },
    /** 内容文本的颜色 */
    contentColor: { type: String as PropType<$AllColorStr>, default: '#666666' },
    /** 内容文本的样式 */
    contentStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
    /** 内容容器的样式 */
    contentViewStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
    /** 是否禁用 */
    disabled: { type: Boolean, default: false },
    /** 是否为最后一个 */
    isLast: { type: Boolean, default: false },
    ...publicStyeProps,
  });

  defineSlots<{
    /** 主体内容 */
    default?: () => void;
    /** 标题 */
    title?: () => void;
    /** 右边的 label */
    rightLabel?: () => void;
  }>();

  const id = getOnlyID('mxp-collapse-item-content-view');
  const newName = computed(() => props.name || `__${id}__`);
  const collapseStore = mxpCollapseStore();
  /** 接收mxp-form组件中的所有prop字段 */
  const mxpCollapseIDInjectKey = ref<CollapseID | undefined>(undefined);
  onMounted(() => {
    /** 解决抖音初始化父子关系初始化较晚问题 */
    mxpCollapseIDInjectKey.value = mxpCollapseIDInjectKey.value ? mxpCollapseIDInjectKey.value : inject<CollapseID>(collapseInjectKey);
  });

  const collapseProps = computed<MxpCollapseProps>(() => {
    if (mxpCollapseIDInjectKey.value && collapseStore.state[mxpCollapseIDInjectKey.value]) {
      return (collapseStore.state[mxpCollapseIDInjectKey.value]?.collapseProps || {}) as MxpCollapseProps;
    } else {
      return {} as MxpCollapseProps;
    }
  });
  const iconPosition = computed(() => collapseProps.value.iconPosition || 'right');
  const duration = computed(() => collapseProps.value.duration || 300);
  const showLastborder = computed(() => collapseProps.value.showLastborder || false);
  const itemBorderColor = computed(() => collapseProps.value.itemBorderColor);
  const unfoldNameList = computed(() => collapseProps.value.unfoldNameList || []);

  /** 是否展开折叠 */
  const isUnFold = ref(unfoldNameList.value.includes(newName.value));
  /** 内容的高度 */
  const contentHeight = ref<$SizeUnitStr>('0px');
  const instance = getCurrentInstance();

  /** 监听展开列表发生变化 */
  watch(
    () => unfoldNameList.value,
    () => {
      isUnFold.value = unfoldNameList.value.includes(newName.value);
    }
  );
  /** 监听的的项展开或收起 */
  watch(
    () => isUnFold.value,
    () => {
      setContentHeight();
    },
    { immediate: true }
  );

  /** icon 最终的样式 */
  const newIconStyle = computed<CSSProperties>(() => {
    const style: CSSProperties = {
      transitionProperty: 'transform',
      transform: `rotate(${isUnFold.value ? -180 : 0}deg)`,
      transitionDuration: `${duration.value}ms`,
      ...props.iconStyle,
    };
    return style;
  });
  const newBorderColor = computed<$AllColorStr | boolean | undefined>(() => {
    return typeof props.borderColor !== 'undefined' ? props.borderColor : typeof itemBorderColor?.value !== 'undefined' ? itemBorderColor.value : true;
  });

  /** 标题View的最终的样式 */
  const newTitleViewStyle = computed<CSSProperties>(() => {
    const style: CSSProperties = { height: '50px', minHeight: props.titleViewMinHeight };
    return { ...style, ...props.titleViewStyle };
  });

  /** 标题的最终的样式 */
  const newTitleStyle = computed<CSSProperties>(() => ({
    paddingLeft: iconPosition.value === 'left' ? '10px' : '0px',
    paddingRight: iconPosition.value === 'right' ? '10px' : '0px',
    ...props.titleStyle,
  }));

  /** 内容文文本的最终本的样式 */
  const newContentTextStyle = computed<CSSProperties>(() => ({
    fontSize: props.contentSize,
    color: props.contentColor,
    paddingLeft: iconPosition.value === 'left' ? '10px' : '0px',
    paddingRight: iconPosition.value === 'right' ? '10px' : '0px',
    ...props.contentStyle,
  }));

  /** 点击切换折叠或展开 */
  function onClick() {
    isUnFold.value = !isUnFold.value;
    setContentHeight();
    if (mxpCollapseIDInjectKey.value && collapseStore.state[mxpCollapseIDInjectKey.value]) {
      typeof collapseStore.state[mxpCollapseIDInjectKey.value]?.changeUnfoldByKey === 'function' &&
        collapseStore.state[mxpCollapseIDInjectKey.value]!.changeUnfoldByKey!(newName.value);
    }
  }

  /** 设置高度 */
  async function setContentHeight() {
    if (isUnFold.value) {
      // 注意当父元素为 flex布局时 一定要给子元素添加 flex-shrink: 0; 否则折叠不能正确获取到子元素的高度
      const size = await getDomSize(`#${id}`, instance);
      contentHeight.value = `${size.height!}px`;
    } else {
      contentHeight.value = '0px';
    }
  }
</script>

<style lang="scss" scoped>
  .mxp-collapse-item {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    overflow: hidden;

    &.disabled {
      opacity: 0.6;
    }

    .title-vessel {
      display: flex;
      flex: 1;
      flex-direction: column;
      align-items: stretch;
      justify-content: space-between;

      .title-view {
        display: flex;
        flex: 1;
        flex-direction: row;
        align-items: center;
        justify-content: flex-end;

        &.hover {
          opacity: 0.7;
        }
      }
    }
    // #ifndef APP-NVUE
    .fold-view {
      // 注意当父元素为 flex一定要给子元素添加 flex-shrink: 0; 否则折叠不能正确获取到子元素的高度
      flex-shrink: 0;
    }
    // #endif
    // stylelint-disable-next-line no-duplicate-selectors
    .fold-view {
      position: relative;
      display: flex;
      flex-direction: column;
      overflow: hidden;
      transition-delay: 0s;
      transition-timing-function: ease;
      transition-property: height;

      .content-view {
        display: flex;
        flex-flow: column nowrap;
        align-items: stretch;

        .content {
          padding: 15px;
        }
      }
    }
  }
</style>
